import { fs, notification } from "@/global";
import { getChunk, getChunkMD5, getChunkNum, getFileMD5 } from "@/bus/utils";
import { chunkHandler, uploadHandler, fileExists, getUsage } from "@/api/file";
import * as path from "path";
import store from "@/store";

const uploadEnum = {
  UPLOAD_QUEUE_STOP: "UPLOAD_QUEUE_STOP",
  UPLOAD_QUEUE_RUNNING: "UPLOAD_QUEUE_RUNNING"
};

let uploadStatus = uploadEnum.UPLOAD_QUEUE_STOP;

const uploadFile = async (filepath, parentId) => {
  const stat = fs.statSync(filepath);
  const size = stat.size;
  const md5 = await getFileMD5(filepath);
  let chunkIndex = await chunkHandler(md5, size);
  let chunk;
  while (chunkIndex !== 0 && uploadStatus === uploadEnum.UPLOAD_QUEUE_RUNNING) {
    chunk = await getChunk(filepath, chunkIndex);
    await uploadHandler(
      chunk,
      md5,
      size,
      chunkIndex,
      await getChunkMD5(chunk),
      path.basename(filepath),
      parentId
    )
      .then(async () => {
        store.commit("UPDATE_UPLOAD_QUEUE_FIRST_ELEMENT_UPLOADED_CHUNK_NUM", 1);
        chunkIndex = await chunkHandler(md5, size);
      })
      .catch(res => {
        //用户存储空间不足
        if (res.code === 80004) {
          this.$message.error(res.msg);
          uploadStatus = uploadEnum.UPLOAD_QUEUE_STOP;
        }
      });
  }
  return !chunkIndex;
};

const stopUploadQueue = function() {
  if (uploadStatus === uploadEnum.UPLOAD_QUEUE_STOP) {
    notification("上传队列已经暂停了");
    return;
  }
  uploadStatus = uploadEnum.UPLOAD_QUEUE_STOP;
  notification("上传队列已暂停");
};

const startUploadQueue = async function() {
  let element = store.getters.world.userInfo.uploadQueue[0];
  let queue = store.getters.world.userInfo.uploadQueue;
  if (element == null) {
    notification("上传队列为空哦！");
    return;
  }
  if (uploadStatus === uploadEnum.UPLOAD_QUEUE_RUNNING) {
    notification("上传队列已经开始了");
    return;
  }
  uploadStatus = uploadEnum.UPLOAD_QUEUE_RUNNING;
  while (queue.length > 0 && uploadStatus === uploadEnum.UPLOAD_QUEUE_RUNNING) {
    let fileMD5 = await getFileMD5(element.filepath);
    await fileExists(fileMD5, element.parentId, element.filename)
      .then(() => {
        afterUpload(element);
        element = store.getters.world.userInfo.uploadQueue[0];
      })
      .catch(async res => {
        if (res.code === 30002) {
          if (await uploadFile(element.filepath, element.parentId)) {
            afterUpload(element);
            element = store.getters.world.userInfo.uploadQueue[0];
          }
        } else if (res.code === 80001) {
          this.$message.error(res.msg);
          //有失败队列强行中断循环
          queue = [];
        }
      });
  }
  uploadStatus = uploadEnum.UPLOAD_QUEUE_STOP;
};

const offerUploadQueue = async function(filepath, parentId) {
  const chunkNum = await getChunkNum(filepath);
  const uploadedChunkNum = 0;
  const filename = path.basename(filepath);
  store.commit("OFFER_UPLOAD_QUEUE", {
    filepath,
    chunkNum,
    uploadedChunkNum,
    parentId,
    filename
  });
  notification("一个新的上传任务添加成功");
};

const afterUpload = function(finishElement) {
  notification("有一个任务上传完成");
  store.commit("OFFER_TRANS_HISTORY", finishElement);
  store.commit("DELETE_ELEMENT_FROM_UPLOAD_QUEUE", finishElement);
  getUsage().then(res => {
    store.commit("SET_USAGE", res.data);
  });
};

export {
  stopUploadQueue,
  startUploadQueue,
  offerUploadQueue,
  uploadStatus,
  uploadEnum
};
